using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Polymod
{
    public class ModelBase<T> : IModel<T>
    {
        IModelFactory _factory;
        InvokerRegistry _registry;
        Dictionary<string, object> _modelState;
        private readonly object _synclock = new object();
        T _value;

        /// <summary>
        /// Gets ModelState
        /// </summary>
        public IDictionary<string, object> ModelState
        {
            get { return _modelState; }
        }

        /// <summary>
        /// Gets Synclock
        /// </summary>
        public object Synclock
        {
            get { return _synclock; }
        }

        public virtual void Initialize(object value, IDictionary<string, object> modelState)
        {
            if (modelState == null)
            {
                throw new System.ArgumentNullException("modelState");
            }
            if (value == null)
            {
                throw new System.ArgumentNullException("value");
            }

            _registry = modelState[Constants.InvokerRegistry] as InvokerRegistry;
            if (_registry == null)
            {
                throw new InvalidOperationException("state does not contain 'Invokers'");
            }

            _factory = modelState[Constants.ModelFactory] as IModelFactory;
            if (_factory == null)
            {
                throw new InvalidOperationException("state does not contain 'ModelFactory'");
            }
            _value = (T)value;
            _modelState = new Dictionary<string, object>(modelState);
        }

        public object Get(string name)
        {
            return _registry.GetValue(this, name);
        }

        public virtual void Set(string name, object value)
        {
            _registry.SetValue(this, name, value);
        }

        object IModel.GetValue()
        {
            return _value;
        }

        public T GetValue()
        {
            return _value;
        }

        public override bool Equals(object obj)
        {
            return _value.Equals(obj);
        }

        public override int GetHashCode()
        {
            return _value.GetHashCode();
        }

        public override string ToString()
        {
            return _value.ToString();
        }
    }
}
